#include "crt_impl.h"

/////////////////////////////////////////////////////////////////////////////////////////
// 
namespace xos
{
    crt_impl::crt_impl()
    {
    }

    crt_impl::~crt_impl()
    {
        term();
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    int crt_impl::init()
    {
        int nRet = 0;
        return nRet;
    }

    int crt_impl::term()
    {
        int nRet = 0;
        return nRet;
    }

    ////////////////////////////////////////////////////////////////////////////////////
    // 

    const char * crt_impl::strrstr( const char * lpszStr, const char * lpszSubStr, bool bCaseSensitive )
    {
        const char * lpStr = 0;

        if( bCaseSensitive )
        {
            const char * p = lpszStr;

            while( 1 )
            {
                p = StrStrA( p, lpszSubStr );

                if( p )
                {
                    lpStr = p;
                    ++p;
                }
                else
                {
                    break;
                }
            }
        }
        else
        {
            lpStr = StrRStrIA( lpszStr, 0, lpszSubStr );
        }

        return lpStr;
    }

    const char * crt_impl::strstr( const char * lpszStr, const char * lpszSubStr, bool bCaseSensitive )
    {
        const char * lpStr = 0;

        if( bCaseSensitive )
        {
            lpStr = StrStrA( lpszStr, lpszSubStr );
        }
        else
        {
            lpStr = StrStrIA( lpszStr, lpszSubStr );
        }

        return lpStr;
    }

    char * crt_impl::strrstr( char * lpszStr, const char * lpszSubStr, bool bCaseSensitive )
    {
        return ( char * )strrstr( lpszStr, lpszSubStr, bCaseSensitive );
    }

    char * crt_impl::strstr( char * lpszStr, const char * lpszSubStr, bool bCaseSensitive )
    {
        return ( char * )strstr( lpszStr, lpszSubStr, bCaseSensitive );
    }

    const char * crt_impl::strrchr( const char * lpszStr, char c )
    {
        return ::strrchr( lpszStr, c );
    }

    const char * crt_impl::strchr( const char * lpszStr, char c )
    {
        return ::strrchr( lpszStr, c );
    }

    char * crt_impl::strrchr( char * lpszStr, char c )
    {
        return ::strrchr( lpszStr, c );
    }

    char * crt_impl::strchr( char * lpszStr, char c )
    {
        return ::strrchr( lpszStr, c );
    }

    int crt_impl::vsnprintf( char * lpszBuf, int nLen, const char * format, va_list argptr )
    {
        return ::vsnprintf_s( lpszBuf, nLen, -1, format, argptr );
    }

    int crt_impl::sprintf( char * buf, int nLen, const char * lpszFormat, ... )
    {
        int nRet = 0;

        va_list  va;
        va_start( va, lpszFormat );
        nRet = _vsnprintf_s( buf, nLen, _TRUNCATE, lpszFormat, va );
        va_end( va );

        return nRet;
    }

    int crt_impl::gets( char * lpszBuf, int nLen )
    {
        int nRet = 0;
        gets_s( lpszBuf, nLen );
        return nRet;
    }

    double crt_impl::atof( const char * lpszStr )
    {
        return ::atof( lpszStr );
    }

    xos_i64 crt_impl::atoi64( const char * lpszStr )
    {
        LONGLONG llData = 0;
        StrToInt64ExA( lpszStr, 0, &llData );
        return llData;
    }

    int crt_impl::atoi( const char * lpszStr )
    {
        return StrToIntA( lpszStr );
    }

    // 
    // nLen include the last '\0'
    // 
    char * crt_impl::strncpy( char * lpszDst, int nLen, const char * lpszSrc )
    {
        return lstrcpynA( lpszDst, lpszSrc, nLen );
    }

    char * crt_impl::strcpy( char * lpszDst, const char * lpszSrc )
    {
        return lstrcpyA( lpszDst, lpszSrc );
    }

    char * crt_impl::strcat( char * lpszDst, const char * lpszSrc )
    {
        return lstrcatA( lpszDst, lpszSrc );
    }

    int crt_impl::strlen( const char * lpszStr )
    {
        return lstrlenA( lpszStr );
    }

    int crt_impl::stricmp( const char * lpszStr1, const char * lpszStr2 )
    {
        return lstrcmpiA( lpszStr1, lpszStr2 );
    }

    int crt_impl::strcmp( const char * lpszStr1, const char * lpszStr2 )
    {
        return lstrcmpA( lpszStr1, lpszStr2 );
    }

    int crt_impl::assert_valid( bool bAssert )
    {
        int nRet = 0;
        assert( bAssert );
        return nRet;
    }

    // 
    // if uSeed is 0, sys will add seed
    // 
    int crt_impl::srand( xos::xos_u32 uSeed )
    {
        int nRet = 0;

        if( 0 == uSeed )
        {
            uSeed = ( xos::xos_u32 )time( 0 );
        }

        ::srand( uSeed );

        return nRet;
    }

    int crt_impl::rand( int nMax )
    {
        int nRet = 0;
        nRet = ::rand() % nMax;
        return nRet;
    }

    // 
    // release
    // 
    int crt_impl::release()
    {
        int nRet = 0;

        term();
        put_back_lock();

        return nRet;
    }
} // xos
